 
/*  rprimv.c
    for use by tm40.c
    Stephen D. Anderson --- June 16, 1995

    Function to read the primary variable and display lower and upper
    range limit.  Does the following in order:

    Checks whether field instrument exists, searches if not.

    Reads lower and upper range of field instrument using HART command 15.
    Indicates errors if any and returns to calling program.  If no errors
    converts range values to floating point.

    Puts up a window to display primary variable, units, and lower and
    upper range limits.  Writes range limits.

    Calls ReadLoop1 until "q" key hit.

    Closes windows and returns to calling program.


    ON ENTRY:  There are no arguments.

    ON EXIT:   Nothing is returned.


    REVISION LOG:


*/

#include "tm40.h"
#include "ieee.h"

void rprimv()
{
    extern byte status1;
    extern byte search(void);
    extern byte found;
    extern byte addr[];
    extern byte status_wind;
    extern void ieee(byte, byte *, float *);
    extern void err(byte);
    extern void err1(byte);

    void Readloop1(byte, byte);
    byte j;
    byte s[20];
    byte wvalue,wunits;
    byte pvoi[20];      /*  prim variable output info.  */
    float lowrange,uprange;
    int i;

    /*  need field instr info? */
    if (!found) found = search();
    if (!found) return;

    /*  first get the lower and upper range.  */
    WpopUp(CNT_HOR,10,20,15,60,2,WHITE|_BLUE,WHITE|_BLUE);
    WputCen("\nGetting Range Info ...");

    i = hartcmd(s, 0, pvoi, 17, addr, 15);

    if (( i & 1) != 0)
    {
        /*  not successful.  */
        err1(15); Wclose(); return;
    }

    /*  check number received bytes.  */
    j = i/256;
    if ( j != 17 )
    {
        /*  not correct number.  */
        err(15); Wclose(); return;
    }

    /*  report any errors.  */
    if (status1 != 0) err(3);

    /*  convert.  */
    Wclose();
    CONVERT_TO_FLOAT(&pvoi[7], &lowrange);
    CONVERT_TO_FLOAT(&pvoi[3], &uprange);

    /*  proceed with function. */
    WpopUp(CNT_HOR,1,20,3,60,2,WHITE|_BLACK,WHITE|_BLACK);
    WputCen("  Hit 'q' key to exit function");
    Wopen(5,10,16,67,2,WHITE|_BLUE,WHITE|_BLUE);
    Wtitle("<<  Primary Variable  >>",TTL_CNT,WHITE|_BLUE);
    Wputs("\n                              VALUE       UNITS\n");
    Wputs("\n  1st (primary) variable");
    Wputs("\n  primary var current");
    Wputf("\n\n\n\n    LOWER RANGE: %8.4g     UPPER RANGE: %8.4g",
        lowrange,uprange);

    wvalue = Wopen(9,40,12,52,5,LGREEN|_BLUE,LGREEN|_BLUE);
    wunits = Wopen(9,53,12,64,5,LGREEN|_BLUE,LGREEN|_BLUE);

    /*  read variables until q key is pressed. */
    j = 0;
    while (j != 'q') 
    {
        Readloop1(wvalue,wunits);
        if (KeyEvent()) j = KwGetCh();
    }
    /*  Get rid of all windows and quit.  */
    Wclose(); Wclose(); Wclose(); Wclose(); return;
}

void Readloop1(byte wvalue, byte wunits)
{

/*  Readloop1 gets the primary variable information by sending HART command
    3.  It checks for errors.  If there are none, it throws away everything
    except variable 1, its units, and the primary variable current.
    It displays variable 1 and the current in the window "wvalue".  It
    displays the units in the window "wunits".  Then it returns to the
    calling program.

    The new information is written with delays so as to make it apparent 
    that continuous updating is occurring.  

    If Readloop1 encounters any of a number of error conditions it halts 
    to display the condition and waits for key hit or mouse click.  Then
    it returns to calling program.

    ON ENTRY:   wvalue is the handle of the window for writing values.
                wunits is the handle of the window for writing units.

    ON EXIT:    nothing is returned.

    REVISION LOG:

*/

    extern byte status1,status2;
    extern void ieee(byte, byte *, float *);
    extern int hartcmd(byte *, byte, byte *, byte, byte *, byte);
    extern void err(byte);
    extern void err1(byte);
    extern byte addr[];

    int i,j;
    byte s[20];
    byte byte_count;
    byte *prdv;
    byte rdv_data[40]; int rdv;
    byte numb_pv;
    #include "units.h"
    float f;

    /*  Send command 3.  */
    rdv = hartcmd(s, 0, rdv_data, 24, addr, 3);
    if (KeyEvent()) return;

    /*  rdv = 1;    */  /*  insert this to test.  */
    /*  command successful?  */
    if ((rdv & 1) != 0)
    {
        /*  not successful.  put up error message. */
        err1(3); return;
    }

    /*  check number received bytes.  should be 9, 14, 19, or 24. */
    byte_count = rdv/256;
    /*  byte_count = 17;  */    /*  insert to test.  */
    if ( !((byte_count == 9) || (byte_count == 14) || 
    (byte_count == 19) || (byte_count == 24)) )
    {
        /*  not correct number. */
        err(3); return;
    }

    /*  report any errors. */
    if (status1 != 0)
    {
        err(3);
        delay(1000);     /*  allow keystroke to quit.  */
    }

    /*  clear windows and delay each new line to show updating. */
    WVclear(wvalue); WVclear(wunits);

    /*  insert to test:
    rdv_data[4] = 
    */

    /*  display primary variable.  */
    prdv = &rdv_data[4];    /*  point to prim var. */
    delay(20);
    /*  insert this to test for NaN. */
    /*
    rdv_data[5] = 0x7f; rdv_data[6] = 0xa0;
    rdv_data[7] = 0; rdv_data[8] = 0;
    */

    CONVERT_TO_FLOAT(prdv+1, &f);
    WVputf(wvalue,"%8.4g\n", f);
    WVputf(wunits,"%s\n", units[*prdv]);

    /*  display pri var current. */
    delay(20);
    CONVERT_TO_FLOAT(rdv_data, &f);
    WVputf(wvalue,"%8.4g\n", f);
    WVputf(wunits,"mA\n");
}

